package com.tbynet.jwp.repository.impl;

import com.jfinal.aop.Inject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.tbynet.jwp.framework.aop.Aop;
import com.tbynet.jwp.framework.core._JwpServiceProvider;
import com.tbynet.jwp.model.Posts;
import com.tbynet.jwp.model.Terms;
import com.tbynet.jwp.repository.spi.PostExportService;
import com.tbynet.jwp.repository.spi.TermService;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

@Aop(PostExportService.class)
public class PostExportServiceImpl extends _JwpServiceProvider<Posts> implements PostExportService {

    @Inject
    private TermService termService;

    @Override
    protected String buildSearchWhereSql(String keyword, List<Object> params) {
        return "";
    }

    @Override
    public List<Posts> getPostsForExport(String status, String category, String dateFrom, String dateTo) {
        StringBuilder sql = new StringBuilder("select * from wp_posts where post_type = 'post'");
        List<Object> params = new ArrayList<>();

        if (StrKit.notBlank(status)) {
            sql.append(" and post_status = ?");
            params.add(status);
        } else {
            sql.append(" and post_status != 'trash'");
        }

        if (StrKit.notBlank(category)) {
            sql.append(" and ID in (select object_id from wp_term_relationships where term_taxonomy_id = ?)");
            params.add(new BigInteger(category));
        }

        if (StrKit.notBlank(dateFrom)) {
            sql.append(" and post_date >= ?");
            params.add(dateFrom);
        }

        if (StrKit.notBlank(dateTo)) {
            sql.append(" and post_date <= ?");
            params.add(dateTo);
        }

        sql.append(" order by post_date desc");

        return getDao().find(sql.toString(), params.toArray());
    }

    @Override
    public String getPostCategories(BigInteger postId) {
        List<Terms> categories = termService.getTerms(postId, "category");
        List<String> categoryNames = new ArrayList<>();
        for (Terms category : categories) {
            categoryNames.add(category.getStr("name"));
        }
        return String.join(", ", categoryNames);
    }

    @Override
    public String getPostTags(BigInteger postId) {
        List<Terms> tags = termService.getTerms(postId, "post_tag");
        List<String> tagNames = new ArrayList<>();
        for (Terms tag : tags) {
            tagNames.add(tag.getStr("name"));
        }
        return String.join(", ", tagNames);
    }

    @Override
    public String escapeCsv(String value) {
        if (value == null) return "";
        // CSV转义：包含逗号、换行、双引号的值需要用双引号包围，内部的双引号要转义为两个双引号
        if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
            return "\"" + value.replace("\"", "\"\"") + "\"";
        }
        return value;
    }

    @Override
    public String escapeXml(String value) {
        if (value == null) return "";
        return value.replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&apos;");
    }

    @Override
    public String getSiteTitle() {
        Record option = Db.findFirst("select option_value from wp_options where option_name = 'blogname'");
        return option != null ? option.getStr("option_value") : "My Site";
    }

    @Override
    public String getSiteUrl() {
        Record option = Db.findFirst("select option_value from wp_options where option_name = 'home'");
        return option != null ? option.getStr("option_value") : "http://localhost";
    }

    @Override
    public String getSiteDescription() {
        Record option = Db.findFirst("select option_value from wp_options where option_name = 'blogdescription'");
        return option != null ? option.getStr("option_value") : "";
    }

    @Override
    public String getPostUrl(Posts post) {
        return getSiteUrl() + "/?p=" + post.getID();
    }

    @Override
    public String getAuthorName(BigInteger authorId) {
        Record user = Db.findFirst("select display_name from wp_users where ID = ?", authorId);
        return user != null ? user.getStr("display_name") : "Unknown";
    }
}